using com.youzu.got.protocol;
using GameFramework.Battle.Core;
using System.Collections.Generic;
using UnityEngine;
using Yoozoo.Libs;

namespace Yoozoo.Gameplay.RTS
{
    /// <summary>
    /// 每个技能对应多个EffectController，每个EffectController里面有多个特效，特效数据EffectControlData
    /// 
    /// </summary>
    public class EffectController : IClass
    {
        public EClassType classType
        {
            get => EClassType.RTS_EffectController;
            set => throw new System.NotImplementedException();
        }

        public class EffectControlData
        {
            public int resourceId;
            public GameObject gameObject;
            public float startTime;
            public float lastTime;
            public Vector3 startPosition;
            public Vector3 endPosition;
            public float moveTime;
            public bool isPlaying;
            public bool isNeedFade;
            public string path;
            public List<Animator> animators = new List<Animator>();
        }

        /// <summary>
        /// 同时播放的特效总量
        /// </summary>
        public static int Count;

        /// <summary>
        /// 同时可播放的最大特效数量
        /// </summary>
        public static int MaxCount = 10;

        /// <summary>
        /// 特效是否创建
        /// </summary>
        private bool isCreated;

        /// <summary>
        /// 特效是否在reset时才销毁
        /// </summary>
        private bool destroyOnReset = false;

        private float startTime = 0;
        private List<EffectControlData> dataList = new List<EffectControlData>();
        private Vector3 defaultAngle = Vector3.zero;
        private float areaDuation = 0;

        public void Play(int effectId,Vector3 position)
        {
            Play(effectId,position,position);
        }

        public void PlayArea(int effectId, Vector3 selfPosition, Vector3 targetPosition,float areaDuation)
        {
            this.areaDuation = areaDuation;
            Play(effectId,selfPosition,targetPosition);
        }
        
        public void Play(int effectId,Vector3 selfPosition, Vector3 targetPosition,int team = -1,bool needChangeEffectColor = false)
        {
            if (!MarchManager.Instance.IsInArena)
            {
                var cameraManager = WorldCameraManager.GetInstance("CameraManager");
                if (!cameraManager.InCamera(selfPosition) && !cameraManager.InCamera(targetPosition))
                    return;
                if (Count >= MaxCount)
                    return;
            }
            
            defaultAngle = (targetPosition - selfPosition).normalized;
            startTime = TimeUtils.GetClientTickTime();
            var dic = RTSBattleEffectManager.Instance.GetEffectConfigs(effectId);
            if (dic == null || dic.Count == 0)
            {
                return;
            }

            var tempNeedChangeEffectColor = needChangeEffectColor;
            var tempTeam = team;
            foreach (var effectConfig in dic.Values)
            {
                var item = effectConfig;
                Vector3 position = targetPosition;
                if (item.bind_target == 1)
                {
                    position = selfPosition;
                }
                var gameObject = ArmyManager.GetResourceById(item.resource_id,false, (obj) =>
                {
                    PlayEffect(obj, item, selfPosition, targetPosition, position,null,tempTeam,tempNeedChangeEffectColor);
                    
                });

                if (gameObject != null)
                {
//                    Debug.LogError("特效"+item.id+"找不到i");
//                    continue;
                    PlayEffect(gameObject, item, selfPosition, targetPosition, position, null, tempTeam,tempNeedChangeEffectColor);
                }
                
            }

            Count++;
            isCreated = true;
        }

        public void PlayBuffEffect(int effectId,Transform parent)
        {
            var cameraManager = WorldCameraManager.GetInstance("CameraManager");
            if (!cameraManager.InCamera(parent.position))
                return;

            if (Count >= MaxCount)
                return;
            
            startTime = TimeUtils.GetClientTickTime();
            var dic = RTSBattleEffectManager.Instance.GetEffectConfigs(effectId);
            if (dic == null || dic.Count == 0)
            {
                return;
            }
            foreach (var effectConfig in dic.Values)
            {
                var item = effectConfig;
                
                var gameObject = ArmyManager.GetResourceById(item.resource_id,false, (obj) =>
                {
                    PlayEffect(obj, item,Vector3.zero, Vector3.zero,Vector3.zero, parent);
                    
                });

                if (gameObject != null)
                {
//                    Debug.LogError("特效"+item.id+"找不到i");
//                    continue;
                    PlayEffect(gameObject, item,Vector3.zero, Vector3.zero,Vector3.zero, parent);
                }
                
            }

            Count++;
            isCreated = true;
            destroyOnReset = true;
        }
        
        private void PlayEffect(GameObject gameObject,RTSBattleEffectManager.EffectConfig item,Vector3 selfPosition, Vector3 targetPosition,Vector3 position, Transform parent = null,int team = -1,bool needChangeEffectColor = false)
        {
            var effectControl = gameObject.GetComponentInChildren<EffectControl>();
            if (effectControl != null)
            {
                effectControl.SetParticle();
            }

            if (needChangeEffectColor)
            {
                var skinnedMeshRenderer = gameObject.GetComponentInChildren<SkinnedMeshRenderer>();
                if (skinnedMeshRenderer)
                {
                    MaterialPropertyBlock block = new MaterialPropertyBlock();
                    skinnedMeshRenderer.GetPropertyBlock(block);
                    if (team == 0)
                    {
                        skinnedMeshRenderer.material.DisableKeyword("_ENEMY_ON");
                    }
                    else
                    {
                        skinnedMeshRenderer.material.EnableKeyword("_ENEMY_ON");
                    }
                    
                    skinnedMeshRenderer.SetPropertyBlock(block);
                }
                
                
            }
            SetParticalHierarchy(gameObject);
            gameObject.SetActive(false);
            if (parent == null)
            {
                gameObject.transform.position = position + new Vector3(item.offset[0].x, item.offset[0].y, item.offset[0].z);
                gameObject.transform.localScale = BattleUtils.EffectScale * item.scale * new Vector3(1f, 1f, 1f);
                if (item.effect_direction == 1)
                {
                    gameObject.transform.forward = defaultAngle;
                }
            }
            else
            {
                gameObject.transform.SetParent(parent);
                gameObject.transform.localPosition = item.offset[0];
                gameObject.transform.localScale = item.scale * new Vector3(1f, 1f, 1f);
            }
            
            float startTime = item.effect_start_time / 1000f;
            float endTime = item.last_time / 1000f;
            bool isFade = false;

            areaDuation = 6;
            if (areaDuation > 0)
            {
                isFade = true;
                endTime = areaDuation;
            }

            var effectControllerData = new EffectControlData
            {
                resourceId = item.resource_id,
                gameObject = gameObject,
                startTime = startTime,
                lastTime = endTime,
                startPosition = selfPosition,
                endPosition = targetPosition,
                //moveTime = moveTime,
                isNeedFade = isFade,
                isPlaying = false,
                path = item.resource_path,
            };
                
            gameObject.GetComponentsInChildren(effectControllerData.animators);
            foreach (var animator in effectControllerData.animators)
            {
                animator.cullingMode = AnimatorCullingMode.AlwaysAnimate;
            }
                
            dataList.Add(effectControllerData);
        }

        private void SetParticalHierarchy(GameObject obj)
        {
            var list = obj.GetComponentsInChildren<ParticleSystem>();
            for (int i = 0; i < list.Length; i++)
            {
                var main = list[i].main;
                main.scalingMode = ParticleSystemScalingMode.Hierarchy;
                //list[i].main = main;
            }
        }

        public void Update()
        {
            var _ct = TimeUtils.GetClientTickTime();
            for (int i = 0; i < dataList.Count; i++)
            {
                if (!destroyOnReset && dataList[i].isPlaying &&
                    _ct >= dataList[i].startTime + dataList[i].lastTime + startTime)
                {
                    foreach (var animator in dataList[i].animators)
                    {
                        animator.cullingMode = AnimatorCullingMode.CullUpdateTransforms;
                    }
                    ArmyManager.RecoverResourceById(dataList[i].resourceId, dataList[i].gameObject);
                    //RTSBattleEffectManager.Instance.RecoverEffect(dataList[i].path, dataList[i].gameObject);
                    dataList.RemoveAt(i);
                    i--;
                }
                else if (!dataList[i].isPlaying && _ct >= dataList[i].startTime + startTime)
                {
                    var data = dataList[i].gameObject;
                    data.SetActive(true);
                    dataList[i].isPlaying = true;
                }
            }
        }
        
        public void OnReset()
        {
            for (int i = 0; i < dataList.Count; i++)
            {
                //RTSBattleEffectManager.Instance.RecoverEffect(dataList[i].path, dataList[i].gameObject);
                foreach (var animator in dataList[i].animators)
                {
                    animator.cullingMode = AnimatorCullingMode.CullUpdateTransforms;
                }
                ArmyManager.RecoverResourceById(dataList[i].resourceId, dataList[i].gameObject);
            }
        
            areaDuation = 0;
            dataList.Clear();
            defaultAngle = Vector3.zero;

            if (isCreated)
                Count--;
            isCreated = false;
            destroyOnReset = false;
        }
    }
}
